July 30, 2021
자바 클래스를 만들 때, 클래스 간의 관계를 판단해보자.
- is a 관계
- has a 관계
🚗 예1) 자동차 클래스 - 엔진 클래스, 바퀴 클래스 …
: ‘자동차 has a 엔진’ 관계를 가지고 있다.
→ 엔진 클래스를 자동차 클래스의 멤버변수화 시키면 된다.
📱 예2) 휴대폰 클래스 - 아이폰 클래스, 안드로이드폰 클래스 …
‘아이폰 is a 휴대폰’ 이라는 관계를 가지고 있다.
→ is a 관계를 가지고 있으면 상속 관계를 만들어서 상속의 이점을 누릴 수 있다.
Object
클래스이다 ⚡문법:
class B
extends
A
{ ... }
🎈 고객 정보를 관리하는 ‘Customer’ 클래스가 있을 때, 이 클래스의 구성요소를 모두 포함하면서 새로운 속성과 기능을 가진 ‘VIPCustomer’ 클래스를 만들어보자.
<Customer.java>
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
}
<VIPCustomer.java>
public class VIPCustomer extends Customer {
// 자식클래스인 VIPCustomer 클래스만의 멤버변수
double saleRatio;
}
<CustomerTest.java>
public class CustomerTest {
public static void main(String[] args) {
VIPCustomer vc1 = new VIPCustomer();
/* VIPCustomer 클래스는 customerName 멤버변수가 없지만,
* Customer 클래스로부터 상속받았기 때문에 사용 가능
*/
vc1.customerName = "홍길동";
System.out.println(vc1.customerName); // 홍길동
}
}
부모클래스인 Customer 클래스에 아래와 같이 생성자를 구현했을 때,
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
// 생성자를 직접 구현 ( => 디폴트 생성자 안만들어짐)
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "Silver";
}
}
VIPCustomer.java에서는 오류가 발생한다. VIPCustomer 클래스의 생성자를 명시하지 않았기 때문에, 컴파일시에 디폴트생성자와 그 안에 super()가 자동 생성된다.
super()가 부모클래스의 디폴트생성자를 호출해야 하는데, Customer클래스에는 디폴트생성자가 없어 오류가 발생하는 것이다.
아래와 같이 VIPCustomer 클래스의 생성자와 super()를 명시해준다.
public class VIPCustomer extends Customer {
double saleRatio;
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName); // 부모클래스의 생성자 호출
super.customerGrade = "VIP"; // 부모클래스의 멤버변수 참조
saleRatio = 0.1;
}
}
<Customer.java>
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "Silver";
}
// 가격을 반환하는 메서드
public double calcPrice(double price) {
return price;
}
}
<VIPCustomer.java>
public class VIPCustomer extends Customer {
double saleRatio;
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName);
super.customerGrade = "VIP";
saleRatio = 0.1;
}
// 메소드 오버라이딩
@Override
public double calcPrice(double price) {
return price * (1-saleRatio); // VIPCustomer 클래스에 맞게 재정의해서 사용
}
}
자식클래스로 객체를 생성할 때, 그 객체를 참조하는 변수의 자료형을 부모클래스로 형변환하여 사용할 수 있다.
Customer vc = new VIPCustomer();
public class CustomerTest {
public static void main(String[] args) {
Customer c = new Customer(10, "장보리");
VIPCustomer v = new VIPCustomer(11, "서리태");
// 묵시적 형변환
Customer vc = new VIPCustomer(12, "김키위");
System.out.println(v.saleRatio); // 0.1
// System.out.println(vc.saleRatio);
// => vc는 Customer 클래스를 참조하는 변수임
// VIPCustomer 클래스만 가지고 있는 saleRatio 변수에 접근 불가
}
}
변수
와 메서드
가 사용하는 메모리는 다르다.
스택 메모리
에 생성됨메서드 영역
에 생성됨
(멤버변수처럼 인스턴스가 생성될때마다 새로 생성되지 않음)public class CustomerTest {
public static void main(String[] args) {
Customer c = new Customer(10, "장보리");
VIPCustomer v = new VIPCustomer(11, "서리태");
Customer vc = new VIPCustomer(12, "김키위");
System.out.println(c.calcPrice(1000)); // 1000.0
System.out.println(v.calcPrice(1000)); // 900.0
// 가상메서드
System.out.println(vc.calcPrice(1000)); // 900.0
}
}